package com.umeox.watch.moto.dataservice.db;

import androidx.annotation.VisibleForTesting;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase;

import com.umeox.moto.common.log.Logger;
import com.umeox.watch.moto.dataservice.base.BaseApp;
import com.umeox.watch.moto.dataservice.db.dao.AlarmDao;
import com.umeox.watch.moto.dataservice.db.dao.BuddyDao;
import com.umeox.watch.moto.dataservice.db.dao.ContactDao;
import com.umeox.watch.moto.dataservice.db.dao.DeviceCodeDao;
import com.umeox.watch.moto.dataservice.db.dao.DeviceDao;
import com.umeox.watch.moto.dataservice.db.dao.FencesDao;
import com.umeox.watch.moto.dataservice.db.dao.ForbidPeriodDao;
import com.umeox.watch.moto.dataservice.db.dao.GroupMemberDao;
import com.umeox.watch.moto.dataservice.db.dao.HeartRateDao;
import com.umeox.watch.moto.dataservice.db.dao.HolderInfoDao;
import com.umeox.watch.moto.dataservice.db.dao.IMGroupDao;
import com.umeox.watch.moto.dataservice.db.dao.LocationInfoDao;
import com.umeox.watch.moto.dataservice.db.dao.LocationPeriodDao;
import com.umeox.watch.moto.dataservice.db.dao.PrayerSettingDao;
import com.umeox.watch.moto.dataservice.db.dao.QuranLearnDao;
import com.umeox.watch.moto.dataservice.db.dao.ServerConfigDao;
import com.umeox.watch.moto.dataservice.db.dao.StepInfoDao;
import com.umeox.watch.moto.dataservice.db.dao.StoryPlayHistoryDao;
import com.umeox.watch.moto.dataservice.db.dao.TasksAttributeDao;
import com.umeox.watch.moto.dataservice.db.dao.WallpaperDao;
import com.umeox.watch.moto.dataservice.db.model.AlarmClock;
import com.umeox.watch.moto.dataservice.db.model.BuddyInfo;
import com.umeox.watch.moto.dataservice.db.model.ContactInfo;
import com.umeox.watch.moto.dataservice.db.model.DeviceCode;
import com.umeox.watch.moto.dataservice.db.model.DeviceConfig;
import com.umeox.watch.moto.dataservice.db.model.Fences;
import com.umeox.watch.moto.dataservice.db.model.ForbidPeriod;
import com.umeox.watch.moto.dataservice.db.model.HeartRate;
import com.umeox.watch.moto.dataservice.db.model.HolderInfo;
import com.umeox.watch.moto.dataservice.db.model.IMGroup;
import com.umeox.watch.moto.dataservice.db.model.IMGroupMember;
import com.umeox.watch.moto.dataservice.db.model.LocationInfo;
import com.umeox.watch.moto.dataservice.db.model.LocationPeriod;
import com.umeox.watch.moto.dataservice.db.model.PrayerSetting;
import com.umeox.watch.moto.dataservice.db.model.QuranLearn;
import com.umeox.watch.moto.dataservice.db.model.ServerConfig;
import com.umeox.watch.moto.dataservice.db.model.StepInfo;
import com.umeox.watch.moto.dataservice.db.model.StoryPlayHistory;
import com.umeox.watch.moto.dataservice.db.model.TasksAttribute;
import com.umeox.watch.moto.dataservice.db.model.WallpaperInfo;


@Database(entities = {AlarmClock.class, BuddyInfo.class, ContactInfo.class, DeviceConfig.class,
        ForbidPeriod.class, LocationPeriod.class, LocationInfo.class, ServerConfig.class,
        StepInfo.class, WallpaperInfo.class, HeartRate.class, DeviceCode.class, HolderInfo.class,
        Fences.class, PrayerSetting.class, QuranLearn.class, StoryPlayHistory.class,
        IMGroup.class, IMGroupMember.class, TasksAttribute.class}, version = AppDataBase.VERSION_CODE, exportSchema = false)
public abstract class AppDataBase extends RoomDatabase {
    private static final String TAG = "AppDataBase";
    public static final int VERSION_CODE = 12;

    private static AppDataBase INSTANCE;

    public abstract DeviceDao deviceDao();

    public abstract AlarmDao alarmDao();

    public abstract BuddyDao buddyDao();

    public abstract ContactDao contactDao();

    public abstract ForbidPeriodDao forbidPeriodDao();

    public abstract LocationInfoDao locationInfoDao();

    public abstract LocationPeriodDao locationPeriodDao();

    public abstract StepInfoDao stepInfoDao();

    public abstract WallpaperDao wallpaperDao();

    public abstract HeartRateDao heartRateDao();

    public abstract ServerConfigDao serverConfigDao();

    public abstract DeviceCodeDao deviceCodeDao();

    public abstract HolderInfoDao holderInfoDao();

    public abstract PrayerSettingDao prayerSettingDao();

    public abstract QuranLearnDao quranLearnDao();

    public abstract FencesDao fencesDao();

    public abstract StoryPlayHistoryDao storyPlayHistoryDao();

    public abstract IMGroupDao iMGroupDao();

    public abstract GroupMemberDao groupMemberDao();

    public abstract TasksAttributeDao tasksAttributeDao();

    private static final Object sLock = new Object();

    @VisibleForTesting
    static final Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            Logger.i(TAG, "MIGRATION_1_2");
            //holder_info 表新增字段
            database.execSQL("ALTER TABLE holder_info ADD COLUMN sportsChallengeRewardsValue INTEGER NOT NULL DEFAULT 0");
        }
    };

    @VisibleForTesting
    static final Migration MIGRATION_2_3 = new Migration(2, 3) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            Logger.i(TAG, "MIGRATION_2_3");
            //holder_info 表新增字段
            database.execSQL("ALTER TABLE device_config ADD COLUMN customWallpaper TEXT");
        }
    };

    @VisibleForTesting
    static final Migration MIGRATION_3_4 = new Migration(3, 4) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            Logger.i(TAG, "MIGRATION_3_4");
            //buddy_info 表新增字段
            database.execSQL("ALTER TABLE buddy_info ADD COLUMN hiddenFeatures TEXT");
        }
    };

    @VisibleForTesting
    static final Migration MIGRATION_4_5 = new Migration(4, 5) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            Logger.i(TAG, "MIGRATION_4_5");
            //holder_info 表新增字段
            database.execSQL("ALTER TABLE device_config ADD COLUMN reportCallLocation INTEGER NOT NULL DEFAULT 0");
            database.execSQL("ALTER TABLE device_config ADD COLUMN reportShutdownLocation INTEGER NOT NULL DEFAULT 0");
        }
    };

    @VisibleForTesting
    static final Migration MIGRATION_5_6 = new Migration(5, 6) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            Logger.i(TAG, "MIGRATION_5_6");
            database.execSQL("ALTER TABLE holder_info ADD COLUMN chantsCounterTotal INTEGER NOT NULL DEFAULT 0");
            database.execSQL("CREATE TABLE IF NOT EXISTS story_play_history (id INTEGER NOT NULL, amount INTEGER NOT NULL, isUpload INTEGER NOT NULL, PRIMARY KEY(id))");
            database.execSQL("CREATE TABLE IF NOT EXISTS im_group (id TEXT NOT NULL, type INTEGER NOT NULL,name TEXT, avatar TEXT, createTime INTEGER NOT NULL,PRIMARY KEY(id))");
            database.execSQL("CREATE TABLE IF NOT EXISTS im_group_member (memberId TEXT NOT NULL, groupId TEXT, type INTEGER NOT NULL,name TEXT, avatar TEXT, avatarIndex INTEGER NOT NULL,createTime INTEGER NOT NULL,PRIMARY KEY(memberId))");
        }
    };

    @VisibleForTesting
    static final Migration MIGRATION_6_7 = new Migration(6, 7) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            Logger.i(TAG, "MIGRATION_6_7");
            //新增im_group表 和 im_group_member
            database.execSQL("CREATE TABLE IF NOT EXISTS im_group (id TEXT NOT NULL, type INTEGER NOT NULL,name TEXT, avatar TEXT, createTime INTEGER NOT NULL,PRIMARY KEY(id))");
            database.execSQL("CREATE TABLE IF NOT EXISTS im_group_member (memberId TEXT NOT NULL, groupId TEXT, type INTEGER NOT NULL,name TEXT, avatar TEXT, avatarIndex INTEGER NOT NULL,createTime INTEGER NOT NULL,PRIMARY KEY(memberId))");
        }
    };

    @VisibleForTesting
    static final Migration MIGRATION_7_8 = new Migration(7, 8) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            Logger.i(TAG, "MIGRATION_7_8");
            //holder_info 表新增字段
            database.execSQL("ALTER TABLE holder_info ADD COLUMN chantsCounterChallengeTotal INTEGER NOT NULL DEFAULT 0");
        }
    };

    @VisibleForTesting
    static final Migration MIGRATION_8_9 = new Migration(8, 9) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            Logger.i(TAG, "MIGRATION_8_9");
            //新增tasks_attribute表
            database.execSQL("CREATE TABLE IF NOT EXISTS tasks_attribute (id INTEGER NOT NULL, type INTEGER NOT NULL,t_action TEXT, title TEXT, content TEXT,reminderTime TEXT,repeatExpression TEXT, additionalInfo TEXT, _id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT)");
        }
    };

    @VisibleForTesting
    static final Migration MIGRATION_9_10 = new Migration(9, 10) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            Logger.i(TAG, "MIGRATION_9_10");
            //新增tasks_attribute表
            database.execSQL("ALTER TABLE device_config ADD COLUMN customGroup INTEGER NOT NULL DEFAULT 0");
        }
    };

    @VisibleForTesting
    static final Migration MIGRATION_10_11 = new Migration(10, 11) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            Logger.i(TAG, "MIGRATION_10_11");
            //新增tasks_attribute表
            database.execSQL("CREATE TABLE IF NOT EXISTS im_group_member_new (_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,memberId TEXT NOT NULL, groupId TEXT, type INTEGER NOT NULL,name TEXT, avatar TEXT, avatarIndex INTEGER NOT NULL,createTime INTEGER NOT NULL)");
            database.execSQL("INSERT INTO im_group_member_new (memberId, groupId, type, name, avatar, avatarIndex,createTime) "
                    + "SELECT memberId, groupId, type, name, avatar, avatarIndex,createTime "
                    + "FROM im_group_member");
            database.execSQL("DROP TABLE im_group_member");
            database.execSQL("ALTER TABLE im_group_member_new RENAME TO im_group_member");
        }
    };

    @VisibleForTesting
    static final Migration MIGRATION_11_12 = new Migration(11, 12) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            Logger.i(TAG, "MIGRATION_11_12");
            //新增tasks_attribute表
            database.execSQL("ALTER TABLE device_config ADD COLUMN qimi INTEGER NOT NULL DEFAULT 0");
        }
    };

//
//    @VisibleForTesting
//    static final Migration MIGRATION_2_4 = new Migration(2, 5) {
//        @Override
//        public void migrate(SupportSQLiteDatabase database) {
//            Log.i(TAG, "MIGRATION_2_5");
//            //创建新的表
//            createNewTable(database);
//            //数据拷贝
//            copyData(database);
//            //移除旧的表
//            removeOldTable(database);
//            //重命名表名
//            renameTable(database);
//
//        }
//    };
//    @VisibleForTesting
//    static final Migration MIGRATION_3_4 = new Migration(3, 5) {
//        @Override
//        public void migrate(SupportSQLiteDatabase database) {
//            Log.i(TAG, "MIGRATION_3_5");
//            database.execSQL("CREATE TABLE IF NOT EXISTS heart_rate (_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, minValue INTEGER NOT NULL, maxValue INTEGER NOT NULL, averageValue INTEGER NOT NULL, measureTime INTEGER NOT NULL, isUpload INTEGER NOT NULL)");
//            database.execSQL("ALTER TABLE device_config ADD COLUMN autoAnswerCallFlag INTEGER NOT NULL DEFAULT 0");
//            database.execSQL("ALTER TABLE device_config ADD COLUMN callLocation INTEGER NOT NULL DEFAULT 0");
//            database.execSQL("ALTER TABLE device_config ADD COLUMN timeZone TEXT");
//
//        }
//    };
//
//    @VisibleForTesting
//    static final Migration MIGRATION_4_5 = new Migration(4, 5) {
//        @Override
//        public void migrate(SupportSQLiteDatabase database) {
//            Log.i(TAG, " Migration MIGRATION_4_5");
//            database.execSQL("ALTER TABLE device_config  ADD COLUMN autoAnswerCallFlag INTEGER NOT NULL DEFAULT 0");
//            database.execSQL("ALTER TABLE device_config  ADD COLUMN callLocation INTEGER NOT NULL DEFAULT 0");
//            database.execSQL("ALTER TABLE device_config  ADD COLUMN timeZone TEXT");
//            Log.d(TAG, "migrate: MIGRATION_4_5 finish");
//        }
//    };
//
//    private static void createNewTable(SupportSQLiteDatabase database) {
//        database.execSQL("CREATE TABLE IF NOT EXISTS alarm_clock_new (_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, alarmId INTEGER NOT NULL, alarmName TEXT, alarmTime TEXT, repeatFlag INTEGER NOT NULL, repeatExpression TEXT, ringType INTEGER NOT NULL, state INTEGER NOT NULL, icon INTEGER NOT NULL, alarmTimeInMillis INTEGER NOT NULL)");
//        database.execSQL("CREATE TABLE IF NOT EXISTS buddy_info_new (friendId TEXT NOT NULL, type INTEGER NOT NULL, name TEXT, photoUrl TEXT, photoPath TEXT, createTime INTEGER NOT NULL, PRIMARY KEY(friendId))");
//        database.execSQL("CREATE TABLE IF NOT EXISTS contact_info_new (contactId INTEGER NOT NULL, rawContactId INTEGER NOT NULL, name TEXT, phone TEXT, photoUrl TEXT, photoPath TEXT, type INTEGER NOT NULL, friendId TEXT, createTime INTEGER NOT NULL, PRIMARY KEY(contactId))");
//        database.execSQL("CREATE TABLE IF NOT EXISTS device_config_new (deviceId TEXT NOT NULL, status INTEGER NOT NULL, bindCode TEXT, unbindCode TEXT, height REAL NOT NULL, weight REAL NOT NULL, audioTypes INTEGER NOT NULL, refusePhone INTEGER NOT NULL, prohibitShutdown INTEGER NOT NULL, nickName TEXT, photoUrl TEXT, forbidVideoCall INTEGER NOT NULL, launched INTEGER NOT NULL, theme INTEGER NOT NULL, inForbidPeriodFlag INTEGER NOT NULL, deviceOffAlarm INTEGER NOT NULL, wallpaper INTEGER NOT NULL,autoAnswerCallFlag INTEGER NOT NULL, callLocation INTEGER NOT NULL, timeZone TEXT, PRIMARY KEY(deviceId))");
//        database.execSQL("CREATE TABLE IF NOT EXISTS forbid_period_new (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, deviceId TEXT, timePeriod TEXT, repeatExpression TEXT)");
//        database.execSQL("CREATE TABLE IF NOT EXISTS location_period_new (deviceId TEXT NOT NULL, timePeriod TEXT, frequency INTEGER NOT NULL, repeatExpression TEXT, PRIMARY KEY(deviceId))");
//        database.execSQL("CREATE TABLE IF NOT EXISTS location_record_new (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, lat REAL NOT NULL, lng REAL NOT NULL, accuracy INTEGER NOT NULL, reportTime TEXT, requestTime TEXT, address TEXT, reportReason INTEGER NOT NULL, reportReasonAttr TEXT, locationMode INTEGER NOT NULL, mcc INTEGER NOT NULL, mnc INTEGER NOT NULL, stepCount INTEGER NOT NULL, batteryVal INTEGER NOT NULL, cellTower TEXT, nearbyCellTowers TEXT, wifiPoints TEXT, network TEXT, locMethod INTEGER NOT NULL, reportFlag INTEGER NOT NULL)");
//        database.execSQL("CREATE TABLE IF NOT EXISTS server_config_new (deviceId TEXT NOT NULL, sslSupport INTEGER NOT NULL, sslServerAddress TEXT, sslServerPort INTEGER NOT NULL, serverAddress TEXT, serverPort INTEGER NOT NULL, fileServerAddress TEXT, fileServerPort INTEGER NOT NULL, PRIMARY KEY(deviceId))");
//        database.execSQL("CREATE TABLE IF NOT EXISTS step_info_new (deviceId TEXT NOT NULL, level INTEGER NOT NULL, percent REAL NOT NULL, totalStepValue TEXT, planStepValue INTEGER NOT NULL, reachGoalTimes INTEGER NOT NULL, reachGoal INTEGER NOT NULL, PRIMARY KEY(deviceId))");
//        database.execSQL("CREATE TABLE IF NOT EXISTS wallpapers_new (id INTEGER NOT NULL, url TEXT, path TEXT, PRIMARY KEY(id))");
//        database.execSQL("CREATE TABLE IF NOT EXISTS heart_rate (_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, minValue INTEGER NOT NULL, maxValue INTEGER NOT NULL, averageValue INTEGER NOT NULL, measureTime INTEGER NOT NULL, isUpload INTEGER NOT NULL)");
//
//    }
//
//    private static void removeOldTable(SupportSQLiteDatabase database) {
//        database.execSQL("DROP TABLE alarm_clock");
//        database.execSQL("DROP TABLE buddy_info");
//        database.execSQL("DROP TABLE contact_info");
//        database.execSQL("DROP TABLE device_config");
//        database.execSQL("DROP TABLE forbid_period");
//        database.execSQL("DROP TABLE location_period");
//        database.execSQL("DROP TABLE location_record");
//        database.execSQL("DROP TABLE server_config");
//        database.execSQL("DROP TABLE step_info");
//        database.execSQL("DROP TABLE wallpapers");
//
//    }
//
//    public static void copyData(SupportSQLiteDatabase database) {
//        try {
//            database.execSQL("INSERT INTO alarm_clock_new (_id, alarmId, alarmName, alarmTime, repeatFlag, repeatExpression, ringType, state, icon, alarmTimeInMillis) "
//                    + "SELECT _id, alarmId, alarmName, alarmTime, repeatFlag, repeatExpression, ringType, state, icon, alarmTimeInMillis "
//                    + "FROM alarm_clock");
//            database.execSQL("INSERT INTO buddy_info_new (friendId, type, name, photoUrl, photoPath, createTime) " +
//                    "SELECT friendId, type, name, photoUrl, photoPath, createTime " +
//                    "FROM buddy_info");
//            database.execSQL("INSERT INTO contact_info_new (contactId, rawContactId, name, phone, photoUrl, photoPath, type, friendId, createTime) " +
//                    "SELECT contactId, rawContactId, name, phone, photoUrl, photoPath, type, friendId, createTime " +
//                    "FROM contact_info");
//            database.execSQL("INSERT INTO device_config_new (deviceId, status, bindCode, unbindCode, height, weight, audioTypes, refusePhone, prohibitShutdown, nickName, photoUrl, forbidVideoCall, launched, theme, inForbidPeriodFlag, deviceOffAlarm, wallpaper) " +
//                    "SELECT deviceId, status, bindCode, unbindCode, height, weight, audioTypes, refusePhone, prohibitShutdown, nickName, photoUrl, forbidVideoCall, launched, theme, inForbidPeriodFlag, deviceOffAlarm, wallpaper " +
//                    "FROM device_config");
//            database.execSQL("INSERT INTO forbid_period_new (id, deviceId, timePeriod, repeatExpression) " +
//                    "SELECT id, deviceId, timePeriod, repeatExpression " +
//                    "FROM forbid_period");
//            database.execSQL("INSERT INTO location_period_new (deviceId, timePeriod, frequency, repeatExpression) " +
//                    "SELECT deviceId, timePeriod, frequency, repeatExpression " +
//                    "FROM location_period");
//            database.execSQL("INSERT INTO location_record_new (id, lat, lng, accuracy, reportTime, requestTime, address, reportReason, reportReasonAttr, locationMode, mcc, mnc, stepCount, batteryVal, cellTower, nearbyCellTowers, wifiPoints, network, locMethod, reportFlag) " +
//                    "SELECT id, lat, lng, accuracy, reportTime, requestTime, address, reportReason, reportReasonAttr, locationMode, mcc, mnc, stepCount, batteryVal, cellTower, nearbyCellTowers, wifiPoints, network, locMethod, reportFlag " +
//                    "FROM location_record");
//
//            database.execSQL("INSERT INTO step_info_new (deviceId, level, percent, totalStepValue, planStepValue, reachGoalTimes, reachGoal) " +
//                    "SELECT deviceId, level, percent, totalStepValue, planStepValue, reachGoalTimes, reachGoal " +
//                    "FROM step_info");
//            database.execSQL("INSERT INTO wallpapers_new (id, url, path) " +
//                    "SELECT id, url, path " +
//                    "FROM wallpapers");
//            database.execSQL("INSERT INTO server_config_new (deviceId, sslSupport, sslServerAddress, sslServerPort, serverAddress, serverPort, fileServerAddress, fileServerPort) " +
//                    "SELECT deviceId, sslSupport, sslServerAddress, sslServerPort, serverAddress, serverPort, fileServerAddress, fileServerPort " +
//                    "FROM server_config");
//        } catch (Exception e) {
//            Log.d(TAG, "copyData: ", e);
//        }
//
//    }
//
//    private static void renameTable(SupportSQLiteDatabase database) {
//        database.execSQL("ALTER TABLE alarm_clock_new RENAME TO alarm_clock");
//        database.execSQL("ALTER TABLE buddy_info_new RENAME TO buddy_info");
//        database.execSQL("ALTER TABLE contact_info_new RENAME TO contact_info");
//        database.execSQL("ALTER TABLE device_config_new RENAME TO device_config");
//        database.execSQL("ALTER TABLE forbid_period_new RENAME TO forbid_period");
//        database.execSQL("ALTER TABLE location_period_new RENAME TO location_period");
//        database.execSQL("ALTER TABLE location_record_new RENAME TO location_record");
//        database.execSQL("ALTER TABLE server_config_new RENAME TO server_config");
//        database.execSQL("ALTER TABLE step_info_new RENAME TO step_info");
//        database.execSQL("ALTER TABLE wallpapers_new RENAME TO wallpapers");
//
//    }


    public static AppDataBase getInstance() {
        synchronized (sLock) {
            if (INSTANCE == null) {

                INSTANCE = Room.databaseBuilder(BaseApp.getInstance()
                                .getApplicationContext(), AppDataBase.class, "umeox_content_wapper.db")
                        .allowMainThreadQueries()
                        .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5,
                                MIGRATION_5_6, MIGRATION_6_7, MIGRATION_7_8, MIGRATION_8_9, MIGRATION_9_10, MIGRATION_10_11,
                                MIGRATION_11_12)
                        .build();
            }
            return INSTANCE;
        }
    }
}
